﻿#include "SettingPage.h"
#include <QDir>
#include <iostream>
#include <ProcessInfoStartuct.h>
#include <QFileInfoList>
#include <QJsonParseError>
#include <StdClassFun.h>

SettingPage::SettingPage( ) {
	getSystemEnv(env);
	env.insertMulti(QString(findPath).toUpper( ), QDir::currentPath( ) + "/");
	envVectorPath = env.values(QString(findPath).toUpper( ));
}

SettingPage::~SettingPage( ) {
	QHash<QString, QJsonDocument*>::iterator iterator = fileMap.begin( );
	QHash<QString, QJsonDocument*>::iterator end = fileMap.end( );
	for( ;iterator != end;++iterator )
		delete iterator.value( );
}

ProcessInfoStartuct::CallData* SettingPage::getCallData(const QJsonObject& jsonObject) {
	ProcessInfoStartuct::CallData* result = new ProcessInfoStartuct::CallData( );
	bool isVi = false;
	if( jsonObject.contains("timeOut") ) {
		if( formatDateTime(jsonObject.value("timeOut").toObject( ), result->timeOut) )
			isVi = true;
	}
	if( jsonObject.contains("Greater") ) {
		if( formatDateTime(jsonObject.value("Greater").toObject( ), result->Greater) )
			isVi = true;
	}
	if( jsonObject.contains("Less") ) {
		if( formatDateTime(jsonObject.value("Less").toObject( ), result->Less) )
			isVi = true;
	}
	if( jsonObject.contains("reStartTimeOut") ) {
		if( formatDateTime(jsonObject.value("reStartTimeOut").toObject( ), result->reStartTimeOut) )
			isVi = true;
	}
	if( getOtherArrt(jsonObject, result->count, result->reStart, result->forceClose) || isVi )
		return result;
	delete result;
	return Q_NULLPTR;
}

int SettingPage::formatDateTime(const QJsonObject& jsonObject
	, QTime& dateTime) {
	int result = 0;
	int hour = 0;
	int minute = 0;
	int second = 0;
	int msec = 0;
	if( jsonObject.contains("hour") ) {
		hour = jsonObject.value("hour").toInt( );
		++result;
	}
	if( jsonObject.contains("minute") ) {
		minute = jsonObject.value("minute").toInt( );
		++result;
	}
	if( jsonObject.contains("second") ) {
		second = jsonObject.value("second").toInt( );
		++result;
	}
	if( jsonObject.contains("msec") ) {
		msec = jsonObject.value("msec").toInt( );
		++result;
	}
	if( !result )
		return result;
	dateTime = QTime(hour, minute, second, msec);
	return result;
}

int SettingPage::getOtherArrt(const QJsonObject& jsonObject
	, qint64& count
	, qint32& reStart
	, qint32& forceClose) {
	int result = 0;
	if( jsonObject.contains("count") ) {
		count = jsonObject.value("count").toInt( );
		++result;
	}
	if( jsonObject.contains("reStart") ) {
		reStart = jsonObject.value("reStart").toInt( );
		++result;
	}
	if( jsonObject.contains("forceClose") ) {
		forceClose = jsonObject.value("forceClose").toInt( );
		++result;
	}
	return result;
}

void SettingPage::formProcessMapObjs(const QJsonDocument& jsonDoc
	, QHash<QString, ProcessInfoStartuct*>& processMap) {
	if( jsonDoc.isObject( ) ) {
		QJsonObject rootJsonObj = jsonDoc.object( );
		auto&& iterator = rootJsonObj.constBegin( );
		auto&& end = rootJsonObj.end( );
		for( ;iterator != end;++iterator ) {
			QJsonObject jsonObject = iterator.value( ).toObject( );
			ProcessInfoStartuct* infoStartuct = formProcessData(jsonObject);
			if( infoStartuct == Q_NULLPTR )
				continue;
			QString key = iterator.key( );
			if( processMap.contains(key) )
				delete processMap.value(key);
			processMap.insert(key, infoStartuct);
		}
	}
}

ProcessInfoStartuct* SettingPage::formProcessData(const QJsonObject& jsonObject) {
	ProcessInfoStartuct* result = new ProcessInfoStartuct;
	int isVi = 0;
	if( jsonObject.contains("absoluteFilePath") ) {
		QString execution = jsonObject.value("absoluteFilePath").toString( );
		QFileInfo info(execution);
		QString currentPath = QDir::currentPath( );
		//std::cout << QString("当前目录:\t" + currentPath + "\n正在查找:\t" + execution).toLocal8Bit( ).constData( ) << std::endl;
		do {
			if( !info.exists( ) ) {
				// 查找 path
				if( !execution.endsWith(executionEndsWith) )
					execution += executionEndsWith;
				int size = envVectorPath.size( );
				//std::cout << QString("envVectorPath.size( ) = %1").arg(size).toLocal8Bit( ).constData( ) << std::endl;
				QDir dir;
				dir.setPath(currentPath);
				//std::cout << QString("当前目录:\t" + currentPath + "\n正在查找:\t" + execution).toLocal8Bit( ).constData( ) << std::endl;
				if( dir.exists(execution) ) {
					execution = currentPath + "/" + execution;
					//std::cout << QString("当前目录:\t" + currentPath + "\n找到:\t" + execution).toLocal8Bit( ).constData( ) << std::endl;
					isVi += 2;
					break;
				}
				for( int index = 0;index < size;++index ) {
					QString path = envVectorPath.value(index);
					dir.setPath(path);
					auto&& exists = dir.exists(execution);
					//std::cout << QString("当前目录:\t" + path + "\n正在查找:\t" + execution).toLocal8Bit( ).constData( ) << std::endl;
					if( exists ) {
						isVi += 2;
						execution = path + "/" + execution;
						//std::cout << QString("当前目录:\t" + path + "\n找到:\t" + execution).toLocal8Bit( ).constData( ) << std::endl;
						break;
					}
				}
			} else {
				//std::cout << QString("当前目录:\t" + info.absolutePath( ) + "\n找到:\t" + execution).toLocal8Bit( ).constData( ) << std::endl;
				isVi += 2;
			}
		} while( false );
		if( isVi == 2 )
			result->setProcessAbsolteFilePath(execution);
		else
			std::cout << QString("\n失去:\t" + execution + "\t配置，请检查配置是否正常\n\n").toLocal8Bit( ).constData( ) << std::endl;
	}
	if( jsonObject.contains("processArguments") ) {
		QJsonArray jsonArray = jsonObject.value("processArguments").toArray( );
		auto&& size = jsonArray.size( );
		QStringList buff;
		for( int index = 0;index < size;++index ) {
			buff << jsonArray.at(index).toString( );
		}
		result->setProcessArguments(buff);
		++isVi;
	}
	if( jsonObject.contains("call") ) {
		ProcessInfoStartuct::CallData* callData = getCallData(jsonObject.value("call").toObject( ));
		if( callData != Q_NULLPTR ) {
			result->setCallData(callData);
			++isVi;
		}
	} else {
		std::cout << QString("发现 call 不存在").toLocal8Bit( ).constData( ) << std::endl;
	}
	if( isVi == 4 )
		return result;
	delete result;
	return Q_NULLPTR;
}

int SettingPage::saveDefaultFileToDisc(const QString& absoluteFilePath
	, const QString& absolutePath
	, QByteArray& byteArray) {
	QFile copyDefaultSettingOperator(":/json/defaultSettings.Json");
	if( !copyDefaultSettingOperator.open(QIODevice::ReadOnly | QIODevice::Text) ) {
		return -2;
	}
	byteArray = copyDefaultSettingOperator.readAll( );
	copyDefaultSettingOperator.close( );
	copyDefaultSettingOperator.setFileName(absoluteFilePath);
	QDir dir;
	if( !dir.mkpath(absolutePath) ) {
		return -10;
	}
	if( !copyDefaultSettingOperator.open(QIODevice::WriteOnly | QIODevice::Text) ) {
		return -3;
	}
	copyDefaultSettingOperator.write(byteArray);
	copyDefaultSettingOperator.close( );
	return 0;
}

int SettingPage::appSettingFile(const QString& file
	, QHash<QString, ProcessInfoStartuct*>& processMap) {
	// 检查是否存在
	QFileInfo info(file);
	QString absoluteFilePath = info.absoluteFilePath( );
	auto&& iterator = fileMap.find(absoluteFilePath);
	auto&& end = fileMap.end( );
	int size = processMap.size( );
	if( iterator == end ) {
		QByteArray byteArray;
		if( !info.exists( ) ) {
			if( !isDefaultSettingPath(absoluteFilePath) ) {
				return -1;
			}
			// 获取默认	
			int defaultFileToDisc = saveDefaultFileToDisc(absoluteFilePath, info.absolutePath( ), byteArray);
			if( defaultFileToDisc )
				return defaultFileToDisc;
		}
		if( byteArray.length( ) < 1 ) {
			QFile readFile(absoluteFilePath);
			if( !readFile.open(QIODevice::ReadOnly | QIODevice::Text) ) {
				return -4;
			}
			byteArray = readFile.readAll( );
		}
		QString string = removeComment(byteArray);
		QJsonParseError error;
		QJsonDocument* jsonDocument = new QJsonDocument(QJsonDocument::fromJson(string.toLatin1( ), &error));
		if( error.error != QJsonParseError::NoError ) {
			return -100;
		}
		fileMap.insert(info.absoluteFilePath( ), jsonDocument);
		formProcessMapObjs(*jsonDocument, processMap);
	} else
		formProcessMapObjs(*iterator.value( ), processMap);
	size = processMap.size( ) - size;
	return size;
}

int SettingPage::releaseFile(const QString& fileName) {
	QFileInfo info(fileName);
	QString absoluteFilePath = info.absoluteFilePath( );
	auto&& iterator = fileMap.find(absoluteFilePath);
	auto&& end = fileMap.end( );
	if( iterator == end )
		return 0;
	delete iterator.value( );
	fileMap.remove(absoluteFilePath);
	return 1;
}
